﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ObjectTransposeApi.Structure;
using System.Reflection;
using ObjectTransposeApi.Helper;

namespace ObjectTransposeApi.Handler.Property
{
    /// <summary/>
    internal class DefaultPropertyHandler : AbstractPropertyHandler
    {
        /// <summary/>
        internal override IEnumerable<QueueStructure> Process(PropertyStructure propertyStructure)
        {
            // fetch the constructor with no parameters
            ConstructorInfo destinationConstructorInfo = ReflectionHelper.FetchConstructor(
                propertyStructure.DestinationPropertyInfo.PropertyType,
                new Type[] { });

            // if not found then exit
            if (destinationConstructorInfo == null)
            {
                return null;
            }

            // read the source property value
            object rawSourceValue = propertyStructure.SourcePropertyInfo.GetValue(
                propertyStructure.Source,
                null);

            // if the value is not set then exit ... this is the last item in the chain
            if (rawSourceValue == null)
            {
                return null;
            }

            // create it
            object destinationValue = Activator.CreateInstance(
                propertyStructure.DestinationPropertyInfo.PropertyType);

            // set the destination value
            propertyStructure.DestinationPropertyInfo.SetValue(
                propertyStructure.Destination, 
                destinationValue, 
                null);

            List<QueueStructure> queueStructures = new List<QueueStructure>();

            // add to the queue
            foreach (object sourceValue in propertyStructure.ExpandCallback(rawSourceValue))
            {
                queueStructures.Add(new QueueStructure(
                    destinationValue,
                    ReflectionHelper.FetchGetSetProperties(destinationValue.GetType()),
                    sourceValue,
                    ReflectionHelper.FetchGetProperties(sourceValue.GetType())));
            }

            // return the objects
            return queueStructures;
        }
    }
}
